e9c5cf1d3e1250205b8d6f755674d222b16e1521,src/java/org/orbeon/oxf/processor/ImageServer.java,ImageServer,filter,#BufferedImage#Iterator#,508

Before Change


                } else if ("line".equals(operation)) {
                    int x1 = XPathUtils.selectIntegerValue(node, "@x1").intValue();
                    int y1 = XPathUtils.selectIntegerValue(node, "@y1").intValue();
                    int x2 = XPathUtils.selectIntegerValue(node, "@x2").intValue();
                    int y2 = XPathUtils.selectIntegerValue(node, "@y2").intValue();
                    Node colorNode = XPathUtils.selectSingleNode(node, "color");
                    if (colorNode != null) {
                        graphics.setColor(getColor(colorNode));

After Change


        int currentHeight = img.getHeight(null);

        // There may be one drawing operation
        List<Node> drawConfiguration = new ArrayList<Node>();

        // Iterate through all transforms
        while (transformIterator.hasNext()) {
            Node node = (Node) transformIterator.next();
            String transformType = XPathUtils.selectStringValueNormalize(node, "@type");
            if ("scale".equals(transformType)) {
                // Scale image
                String qualityString = XPathUtils.selectStringValueNormalize(node, "quality");
                boolean lowQuality = "low".equals(qualityString);
                boolean scaleUp = selectBooleanValue(node, "scale-up", DEFAULT_SCALE_UP);
                String widthString = XPathUtils.selectStringValueNormalize(node, "width");
                int width;
                int height;
                if (widthString == null) {
                    // There must be a maximum, use it to compute width and height
                    String maxSizeString = XPathUtils.selectStringValueNormalize(node, "max-size");
                    String maxWidthString = XPathUtils.selectStringValueNormalize(node, "max-width");
                    String maxHeightString = XPathUtils.selectStringValueNormalize(node, "max-height");
                    if (maxSizeString != null) {
                        int maxSize = Integer.parseInt(maxSizeString);
                        double scale = (currentWidth > currentHeight)
                                ? ((double) maxSize / (double) currentWidth)
                                : ((double) maxSize / (double) currentHeight);
                        width = (int) (scale * currentWidth);
                        height = (int) (scale * currentHeight);
                    } else if (maxWidthString != null) {
                        int maxWidth = Integer.parseInt(maxWidthString);
                        double scale = (double) maxWidth / (double) currentWidth;
                        width = (int) (scale * currentWidth);
                        height = (int) (scale * currentHeight);
                    } else {
                        int maxHeight = Integer.parseInt(maxHeightString);
                        double scale = (double) maxHeight / (double) currentHeight;
                        width = (int) (scale * currentWidth);
                        height = (int) (scale * currentHeight);
                    }
                } else {
                    // Width and height are specified directly
                    String heightString = XPathUtils.selectStringValueNormalize(node, "height");
                    width = Integer.parseInt(widthString);
                    height = Integer.parseInt(heightString);
                }
                // Make sure we don't scale up if not allowed to
                if (!scaleUp && (width > currentWidth || height > currentHeight)) {
                    width = currentWidth;
                    height = currentHeight;
                }
                // Chain filter if needed
                if (currentWidth != width || currentHeight != height) {
                    ImageFilter scaleFilter = lowQuality ? new ReplicateScaleFilter(width, height) : new AreaAveragingScaleFilter(width, height);
                    producer = new FilteredImageSource(producer, scaleFilter);
                    // Remember current width and height
                    currentWidth = width;
                    currentHeight = height;
                }
            } else if ("crop".equals(transformType)) {
                // Crop image
                int x = selectIntValue(node, "x", 0);
                int y = selectIntValue(node, "y", 0);
                int width = selectIntValue(node, "width", currentWidth - x);
                int height = selectIntValue(node, "height", currentHeight - y);
                // Calculate actual size
                Rectangle2D rect = new Rectangle(x, y, width, height);
                Rectangle2D imageRect = new Rectangle(0, 0, currentWidth, currentHeight);
                Rectangle2D intersection = rect.createIntersection(imageRect);

                // Make sure image is not empty
                if (intersection.getWidth() < 0 || intersection.getHeight() < 0) {
                    logger.info("Resulting image is empty after crop!");
                    throw new OXFException("Resulting image is empty after crop!");
                }

                // Chain filter if needed
                if (!imageRect.equals(intersection)) {
                    ImageFilter cropFilter = new CropImageFilter((int) intersection.getX(),
                            (int) intersection.getY(), (int) intersection.getWidth(), (int) intersection.getHeight());
                    producer = new FilteredImageSource(producer, cropFilter);
                    // Remember current width and height
                    currentWidth = (int) intersection.getWidth();
                    currentHeight = (int) intersection.getHeight();
                }
            } else if ("draw".equals(transformType)) {
                // Don't do anything for now, this must be the last step
                drawConfiguration.add(node);
            }
        }

        Image filteredImg = Toolkit.getDefaultToolkit().createImage(producer);

        // Create resulting image
        BufferedImage newImage = new BufferedImage(currentWidth, currentHeight, srcImage.getType());
        Graphics2D graphics = newImage.createGraphics();
        graphics.drawImage(filteredImg, null, null);
        // Check for drawing operation
        for (Node drawConfigNode: drawConfiguration) {
            for (Iterator i = XPathUtils.selectIterator(drawConfigNode, "rect | fill | line"); i.hasNext();) {
                Node node = (Node) i.next();
                String operation = XPathUtils.selectStringValueNormalize(node, "name()");
                if ("rect".equals(operation)) {
                    int x = XPathUtils.selectIntegerValue(node, "@x");
                    int y = XPathUtils.selectIntegerValue(node, "@y");
                    int width = XPathUtils.selectIntegerValue(node, "@width") - 1;
                    int height = XPathUtils.selectIntegerValue(node, "@height") - 1;
                    Node colorNode = XPathUtils.selectSingleNode(node, "color");
                    if (colorNode != null) {
                        graphics.setColor(getColor(colorNode));
                    }
                    graphics.drawRect(x, y, width, height);
                } else if ("fill".equals(operation)) {
                    int x = XPathUtils.selectIntegerValue(node, "@x");
                    int y = XPathUtils.selectIntegerValue(node, "@y");
                    int width = XPathUtils.selectIntegerValue(node, "@width");
                    int height = XPathUtils.selectIntegerValue(node, "@height");
                    Node colorNode = XPathUtils.selectSingleNode(node, "color");
                    if (colorNode != null) {
                        graphics.setColor(getColor(colorNode));
                    }
                    graphics.fillRect(x, y, width, height);
                } else if ("line".equals(operation)) {
                    int x1 = XPathUtils.selectIntegerValue(node, "@x1");
                    int y1 = XPathUtils.selectIntegerValue(node, "@y1");
                    int x2 = XPathUtils.selectIntegerValue(node, "@x2");
                    int y2 = XPathUtils.selectIntegerValue(node, "@y2");
                    Node colorNode = XPathUtils.selectSingleNode(node, "color");
                    if (colorNode != null) {
                        graphics.setColor(getColor(colorNode));